{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/atrask/anaconda/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n",
      "  return f(*args, **kwds)\n",
      "/Users/atrask/anaconda/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n",
      "  return f(*args, **kwds)\n",
      "/Users/atrask/anaconda/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n",
      "  return f(*args, **kwds)\n",
      "/Users/atrask/anaconda/lib/python3.6/importlib/_bootstrap.py:205: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88\n",
      "  return f(*args, **kwds)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Setting up Sandbox...\n",
      "Done!\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "import json\n",
    "import requests\n",
    "import random\n",
    "\n",
    "import torch as th\n",
    "from torch import nn\n",
    "import syft as sy\n",
    "\n",
    "sy.create_sandbox(globals(), verbose=False)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from syft.codes import MSGTYPE\n",
    "from syft import serde\n",
    "\n",
    "class CommandCreator():\n",
    "    \n",
    "    def __init__(self, id):\n",
    "        self.id = id\n",
    "        \n",
    "    def send_msg(self, msg_type, message, location):\n",
    "        # Step 0: combine type and message\n",
    "        message = (msg_type, message)\n",
    "\n",
    "        # Step 1: serialize the message to simple python objects\n",
    "        bin_message = serde.serialize(message)\n",
    "        \n",
    "        return bin_message\n",
    "    \n",
    "    def send_command(self, recipient, message):\n",
    "        \"\"\"\n",
    "        Send a command through a message to a recipient worker\n",
    "        :param recipient:\n",
    "        :param message:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "\n",
    "        response = self.send_msg(MSGTYPE.CMD, message, location=recipient)\n",
    "\n",
    "        return response"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import msgpack"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[2,\n",
       " [1,\n",
       "  [2,\n",
       "   [b'__add__',\n",
       "    [10, [36593675293, 89052606580, b'me', None, [4]]],\n",
       "    [2, [[10, [36593675293, 89052606580, b'me', None, [4]]]]]]]]]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = th.tensor([1,2,3,4]).create_pointer()\n",
    "x.owner = CommandCreator(\"steve\")\n",
    "y = x + x\n",
    "msgpack.loads(y[1:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'Tensor \"27412296840\" not found on worker \"me\"!!! You just tried to interact with an object ID:27412296840 on worker me which does not exist!!! Use .send() and .get() on all your tensors to make sure they\\'reon the same machines. If you think this tensor does exist, check the ._objects dictionaryon the worker and see for yourself!!! The most common reason this error happens is because someone calls.get() on the object\\'s pointer without realizing it (which deletes the remote object and sends it to the pointer). Check your code to make sure you haven\\'t already called .get() on this pointer!!!'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/workers/base.py\u001b[0m in \u001b[0;36mget_obj\u001b[0;34m(self, obj_id)\u001b[0m\n\u001b[1;32m    333\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 334\u001b[0;31m             \u001b[0mobj\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_objects\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mobj_id\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    335\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 27412296840",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-4-395ad08db0a1>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mserde\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdeserialize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/serde.py\u001b[0m in \u001b[0;36mdeserialize\u001b[0;34m(binary, worker, compressed, compress_scheme)\u001b[0m\n\u001b[1;32m    155\u001b[0m     \u001b[0;31m# as msgpack's inability to serialize torch tensors or ... or\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    156\u001b[0m     \u001b[0;31m# python slice objects\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 157\u001b[0;31m     \u001b[0;32mreturn\u001b[0m \u001b[0m_detail\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mworker\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msimple_objects\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    158\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    159\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/serde.py\u001b[0m in \u001b[0;36m_detail\u001b[0;34m(worker, obj)\u001b[0m\n\u001b[1;32m    925\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    926\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 927\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mdetailers\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mworker\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    928\u001b[0m     \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    929\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/serde.py\u001b[0m in \u001b[0;36m_detail_collection_tuple\u001b[0;34m(worker, my_tuple)\u001b[0m\n\u001b[1;32m    485\u001b[0m     \u001b[0;31m# Step 1: deserialize each part of the collection\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    486\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mpart\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mmy_tuple\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 487\u001b[0;31m         \u001b[0mpieces\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_detail\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mworker\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpart\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    488\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    489\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpieces\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/serde.py\u001b[0m in \u001b[0;36m_detail\u001b[0;34m(worker, obj)\u001b[0m\n\u001b[1;32m    925\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    926\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 927\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mdetailers\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mworker\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    928\u001b[0m     \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    929\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/serde.py\u001b[0m in \u001b[0;36m_detail_collection_tuple\u001b[0;34m(worker, my_tuple)\u001b[0m\n\u001b[1;32m    485\u001b[0m     \u001b[0;31m# Step 1: deserialize each part of the collection\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    486\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0mpart\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mmy_tuple\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 487\u001b[0;31m         \u001b[0mpieces\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_detail\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mworker\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpart\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    488\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    489\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpieces\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/serde.py\u001b[0m in \u001b[0;36m_detail\u001b[0;34m(worker, obj)\u001b[0m\n\u001b[1;32m    925\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    926\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 927\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mdetailers\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mworker\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    928\u001b[0m     \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    929\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/serde.py\u001b[0m in \u001b[0;36mdetail\u001b[0;34m(worker, tensor_tuple)\u001b[0m\n\u001b[1;32m    752\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mworker_id\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mworker\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mid\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    753\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 754\u001b[0;31m         \u001b[0mtensor\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mworker\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_obj\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mid_at_location\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    755\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    756\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mpoint_to_attr\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mtensor\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/Users/atrask/anaconda/lib/python3.6/site-packages/syft-0.1.0a1-py3.6.egg/syft/workers/base.py\u001b[0m in \u001b[0;36mget_obj\u001b[0;34m(self, obj_id)\u001b[0m\n\u001b[1;32m    355\u001b[0m                     \u001b[0;34m\"make sure you haven't already called .get() on this pointer!!!\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    356\u001b[0m                 )\n\u001b[0;32m--> 357\u001b[0;31m                 \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    358\u001b[0m             \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    359\u001b[0m                 \u001b[0;32mraise\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'Tensor \"27412296840\" not found on worker \"me\"!!! You just tried to interact with an object ID:27412296840 on worker me which does not exist!!! Use .send() and .get() on all your tensors to make sure they\\'reon the same machines. If you think this tensor does exist, check the ._objects dictionaryon the worker and see for yourself!!! The most common reason this error happens is because someone calls.get() on the object\\'s pointer without realizing it (which deletes the remote object and sends it to the pointer). Check your code to make sure you haven\\'t already called .get() on this pointer!!!'"
     ]
    }
   ],
   "source": [
    "sy.serde.deserialize(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "sy.local_worker.id = \"bob\"# + str(random.randint(0,1e10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "url = \"http://127.0.0.1:5000\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.],\n",
       "        [0.]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# request model\n",
    "res = requests.get(url+\"/get_model\")\n",
    "m = sy.serde.deserialize(res.content)\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = th.ones(4,2)\n",
    "ptr = data.create_pointer()\n",
    "ptr = ptr.ser()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Response [200]>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# request model\n",
    "res = requests.post(url+\"/send_data\",data=ptr,headers={'Content-Type': 'application/octet-stream'})\n",
    "res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.],\n",
       "        [0.]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "m = sy.serde.deserialize(res.content)\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.],\n",
       "        [0.],\n",
       "        [0.],\n",
       "        [0.]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.mm(m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Linear(in_features=2, out_features=1, bias=False)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Iniitalize A Toy Model\n",
    "model = nn.Linear(2, 1, bias=False)\n",
    "model.send(bob)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "bob.log_msgs = True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[b'0\\x92\\x02\\x92\\x02\\x92\\x01\\x94\\xcf\\x00\\x00\\x00\\t\\x8c\\x8d\\xd8\\x06\\x96\\xcf\\x00\\x00\\x00\\x05\\xadw\\xe6*\\xda\\x01_\\x80\\x02\\x8a\\nl\\xfc\\x9cF\\xf9 j\\xa8P\\x19.\\x80\\x02M\\xe9\\x03.\\x80\\x02}q\\x00(X\\x10\\x00\\x00\\x00protocol_versionq\\x01M\\xe9\\x03X\\r\\x00\\x00\\x00little_endianq\\x02\\x88X\\n\\x00\\x00\\x00type_sizesq\\x03}q\\x04(X\\x05\\x00\\x00\\x00shortq\\x05K\\x02X\\x03\\x00\\x00\\x00intq\\x06K\\x04X\\x04\\x00\\x00\\x00longq\\x07K\\x04uu.\\x80\\x02ctorch._utils\\n_rebuild_tensor_v2\\nq\\x00((X\\x07\\x00\\x00\\x00storageq\\x01ctorch\\nFloatStorage\\nq\\x02X\\x0f\\x00\\x00\\x00140431083661328q\\x03X\\x03\\x00\\x00\\x00cpuq\\x04K\\x02Ntq\\x05QK\\x00K\\x01K\\x02\\x86q\\x06K\\x02K\\x01\\x86q\\x07\\x89ccollections\\nOrderedDict\\nq\\x08)Rq\\ttq\\nRq\\x0b.\\x80\\x02]q\\x00X\\x0f\\x00\\x00\\x00140431083661328q\\x01a.\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x83\\xed\\x1d?\\xee&\\xd5>\\xc0\\xc0\\xc0\\xc0\\xc3\\xc0',\n",
       " b\"0\\x92\\x02\\x92\\x02\\x92\\x01\\x94\\xcf\\x00\\x00\\x00\\x10\\xc5o\\x0b\\x1b\\x96\\xcf\\x00\\x00\\x00\\x0b\\x91r.\\x86\\xda\\x01_\\x80\\x02\\x8a\\nl\\xfc\\x9cF\\xf9 j\\xa8P\\x19.\\x80\\x02M\\xe9\\x03.\\x80\\x02}q\\x00(X\\x10\\x00\\x00\\x00protocol_versionq\\x01M\\xe9\\x03X\\r\\x00\\x00\\x00little_endianq\\x02\\x88X\\n\\x00\\x00\\x00type_sizesq\\x03}q\\x04(X\\x05\\x00\\x00\\x00shortq\\x05K\\x02X\\x03\\x00\\x00\\x00intq\\x06K\\x04X\\x04\\x00\\x00\\x00longq\\x07K\\x04uu.\\x80\\x02ctorch._utils\\n_rebuild_tensor_v2\\nq\\x00((X\\x07\\x00\\x00\\x00storageq\\x01ctorch\\nFloatStorage\\nq\\x02X\\x0f\\x00\\x00\\x00140431140170272q\\x03X\\x03\\x00\\x00\\x00cpuq\\x04K\\x02Ntq\\x05QK\\x00K\\x01K\\x02\\x86q\\x06K\\x02K\\x01\\x86q\\x07\\x89ccollections\\nOrderedDict\\nq\\x08)Rq\\ttq\\nRq\\x0b.\\x80\\x02]q\\x00X\\x0f\\x00\\x00\\x00140431140170272q\\x01a.\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xb0\\xcdR>\\xc0_'<\\xc0\\xc0\\xc0\\xc0\\xc3\\xc0\"]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bob.msg_history"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
